#include "tasksession.h"
#include <QDebug>
#include <QRegExp>
#include <QByteArray>
#include "Json/cJSON.h"

TaskSession::TaskSession(QTcpSocket *skt, HttpServer *parent) : QObject(parent)
{
    tManager = TempManager::manager();
    taskSocket = skt;
    taskProgress = 0;
    connect(taskSocket, SIGNAL(readyRead()), this, SLOT(readSessionData()), Qt::DirectConnection);
    echarts = NULL;
    taskType = TASK_NONE;
}

void TaskSession::setSocket(QTcpSocket *skt)
{
    if(taskSocket != NULL)
        taskSocket->deleteLater();
    taskSocket = skt;
    connect(taskSocket, SIGNAL(readyRead()), this, SLOT(readSessionData()), Qt::DirectConnection);
}

TaskSession::~TaskSession()
{
    qDebug()<<"[TaskSession]:delete";
    taskSocket->deleteLater();
}

void TaskSession::recvParams(QByteArray qba)
{
    QString paramStr = QString::fromUtf8(qba);
    QStringList params = paramStr.split("&");
    QString opt = getParam("opt", params);
    curOpt = opt;
    qDebug()<<"[TaskSession]:"<<opt;
    if(opt.isEmpty())
        return;
    else if(opt == "GetAllDev")
    {
        taskType = TASK_OTHERS;
        qDebug()<<"GetAllDev";
        QStringList devList = tManager->getTempRecordList();
        writeData("GetAllDev",getAllDev(devList));
        sessionFinishSlot();
    }
    else if(opt == "SetDevParam")
    {
        taskType = TASK_OTHERS;
        qDebug()<<"SetDevParam";
        QString dev = getParam("dev", params);
        QString name = strTrans(getParam("name", params));
        writeData("SetDevParam", SetDevParam(dev, name));
        sessionFinishSlot();
    }
    else if(opt == "CreateDevRecord")
    {
        if(taskType == TASK_GET_RECORD)
        {
            fastReturn("任务已经开始", 1);
            return;
        }
        taskType = TASK_GET_RECORD;
        qDebug()<<"CreateDevRecord";
        QStringList devs = getParam("devs", params).split("%2C", QString::SkipEmptyParts);
        QString begin = getParam("begin", params);
        QString end = getParam("end", params);
        CreateDevRecord(devs, begin, end);
    }
    else if(opt == "GetDevRecord")
    {
        qDebug()<<"GetDevRecord";
        writeData("GetDevRecord", GetDevRecord());
    }
    else if(opt == "ExportDevRecord")
    {
        if(taskType == TASK_EXPORT_RECORD)
        {
            fastReturn("任务已经开始", 1);
            return;
        }
        taskType = TASK_EXPORT_RECORD;
        qDebug()<<"ExportDevRecord";
        QStringList devs = getParam("devs", params).split("%2C", QString::SkipEmptyParts);
        QString begin = getParam("begin", params);
        QString end = getParam("end", params);
        ExportDevRecord(devs, begin, end);
    }
    else if(opt == "CheckExportProgress")
    {
        qDebug()<<"CheckExportProgress";
        writeData("CheckExportProgress", CheckExportProgress());
    }
}

QString TaskSession::strTrans(QString str)
{
    QByteArray qba = QByteArray::fromPercentEncoding(str.toLocal8Bit());
    qDebug()<<qba.toHex();
    return  QString::fromUtf8(qba);
}

QString TaskSession::getParam(QString paramName, QStringList params)
{
    QString regStr = QString("%1=(.+)").arg(paramName);
    QRegExp reg(regStr);
    int idx;
    idx = params.indexOf(reg);

    if(idx == -1)
        return QString();

    idx = reg.indexIn(params.at(idx));

    if(idx == -1)
        return QString();

    qDebug()<<"[getParam]"<<paramName<<reg.cap(1);
    return reg.cap(1);
}

QByteArray TaskSession::getAllDev(QStringList devList)
{
    cJSON* tJson = cJSON_CreateObject();
    if(devList.isEmpty())
    {
        QByteArray msg = QString::fromUtf8("没有上线设备").toUtf8();
        cJSON_AddItemToObject(tJson, "code", cJSON_CreateNumber(-1));
        cJSON_AddItemToObject(tJson, "msg", cJSON_CreateString(msg.data()));
        QByteArray ret = QByteArray(cJSON_Print(tJson));
        cJSON_Delete(tJson);
        return ret;
    }
    cJSON_AddItemToObject(tJson, "code", cJSON_CreateNumber(0));
    cJSON_AddItemToObject(tJson, "msg", cJSON_CreateString("success"));
    cJSON* tData = cJSON_CreateArray();
    HttpServer* par = static_cast<HttpServer*> (parent());

    foreach(QString dev, devList)
    {
        cJSON* devData = cJSON_CreateObject();
        TempCase* tCase = par->getDevCase(dev);
        QByteArray DEV_NAME;
        float CUR_TEMP;
        float CUR_HUM;
        QByteArray STATE;
        QByteArray DEV_ID;


        if(tCase == NULL)
        {
            CUR_TEMP = 0;
            CUR_HUM = 0;
            STATE = "O";
        }
        else
        {
            CUR_TEMP = tCase->getCurTemp();
            CUR_HUM = tCase->getCurHum();
            STATE = tCase->getCurStateStr().toLocal8Bit();
        }
        DEV_ID = dev.toLocal8Bit();
        DEV_NAME = tManager->getDevName(DEV_ID).toLocal8Bit();

        cJSON_AddItemToObject(devData, "DEV_ID", cJSON_CreateString(DEV_ID.data()));
        cJSON_AddItemToObject(devData, "DEV_NAME", cJSON_CreateString(DEV_NAME.data()));
        cJSON_AddItemToObject(devData, "CUR_TEMP", cJSON_CreateNumber(CUR_TEMP));
        cJSON_AddItemToObject(devData, "CUR_HUM", cJSON_CreateNumber(CUR_HUM));
        cJSON_AddItemToObject(devData, "STATE", cJSON_CreateString(STATE.data()));
        cJSON_AddItemToArray(tData, devData);
    }
    cJSON_AddItemToObject(tJson, "data", tData);
    QByteArray ret = QByteArray(cJSON_Print(tJson));
    cJSON_Delete(tJson);
    return ret;
}

QByteArray TaskSession::SetDevParam(QString dev, QString name)
{
    if(name.isEmpty())
    {
        return QString("{\
                          \"code\": -1,\
                          \"msg\": \"%1\"\
                      }").arg(QString::fromUtf8("设备名为空")).toLocal8Bit();
    }
    tManager->setDevName(dev, name);
    emit updateDevInfo(dev);
    return QByteArray("{\
                      \"code\": 0,\
                      \"msg\": \"success\"\
                      }");
}

void TaskSession::CreateDevRecord(QStringList devList, QString begin, QString end)
{
    if(echarts != NULL)
    {
        fastReturn("正在生成数据", -1);
        return;
    }
    if(devList.isEmpty())
    {
        fastReturn("查询设备不能为空", -1);
        return;
    }

    taskProgress = 0;
    echarts = new JECharts();
    echarts->devList.clear();
    echarts->devList<<devList;
    echarts->legendList.clear();
    eThread = new QThread();
    eThread->start();
    echarts->moveToThread(eThread);
    connect(eThread, SIGNAL(finished()), echarts, SLOT(deleteLater()));
    connect(eThread, SIGNAL(finished()), eThread, SLOT(deleteLater()));
    connect(this, SIGNAL(newEchartsTask(QDate,QDate)), echarts, SLOT(creatEchartJson(QDate,QDate)));
    connect(echarts, SIGNAL(updateTaskProgress(int)), this, SLOT(updateTaskProgress(int)));

    foreach(QString dev, echarts->devList)
    {
        QString strName = tManager->getDevName(dev);
        if(strName.isEmpty())
            echarts->legendList<<dev;
        else
            echarts->legendList<<strName;
    }

    fastReturn("success", 0);
    emit newEchartsTask(QDate::fromString(begin, "yyyyMMdd"), QDate::fromString(end, "yyyyMMdd"));
//    echarts->legendList<<"03B91ACD";
//    QByteArray ret = echarts->getEchartJson(&taskProgress, QDate::fromString(begin, "yyyyMMdd"), QDate::fromString(end, "yyyyMMdd"));
    return;
}

QByteArray TaskSession::GetDevRecord()
{
    QString retStr;
    if(taskType != TASK_GET_RECORD)
    {
        retStr = QString("{\
                         \"code\": -1,\
                         \"msg\": \"%1\"\
                        }").arg(QString::fromUtf8("任务状态错误"));
        return retStr.toUtf8();
    }

    if(taskProgress == 100)
    {
        QByteArray ret = QByteArray(echarts->getEchartRst());
        eThread->quit();
        eThread->wait();
        taskType = TASK_NONE;
        QTimer::singleShot(2000, this, SLOT(sessionFinishSlot()));
        return ret;
    }
    else
    {
        retStr = QString("{\
                        \"code\": 1,\
                        \"msg\": \"%1\",\
                        \"progress\":%2\
                        }").arg(QString::fromUtf8("正在生成数据")).arg(taskProgress);
        return retStr.toUtf8();
    }
}

void TaskSession::ExportDevRecord(QStringList devList, QString begin, QString end)
{
//    QProcess processClear;
    QString pdfPath = qApp->applicationDirPath()+PATH_TEMP_PDF;
//    processClear.execute(QString("rm %1*.pdf").arg(pdfPath));
//    processClear.waitForFinished();
    QByteArray qba = QString("rm %1*.pdf").arg(pdfPath).toLocal8Bit();
    qDebug()<<"[processClear]"<<qba;
    system(qba.data());
    taskProgress = 0;
    if(devList.isEmpty())
    {
        fastReturn("设备不能为空", -1);
        return;
    }

    tempToPdf = new TempToPdf();
    pThread = new QThread();
    pThread->start();
    tempToPdf->moveToThread(pThread);
    connect(pThread, SIGNAL(finished()), tempToPdf, SLOT(deleteLater()));
    connect(pThread, SIGNAL(finished()), pThread, SLOT(deleteLater()));
    connect(tempToPdf, SIGNAL(updateProgress(int)), this, SLOT(updateTaskProgress(int)));
    connect(this, SIGNAL(newPdfTask(QStringList,QDate,QDate)), tempToPdf, SLOT(creatTempPdf(QStringList,QDate,QDate)));
    fastReturn("success", 0);
    emit newPdfTask(devList, QDate::fromString(begin, "yyyyMMdd"), QDate::fromString(end, "yyyyMMdd"));
//    recordName = QString("%1_%2.tar.bz2").arg(begin).arg(end);
//    tempToPdf->creatTempPdf(devList, QDate::fromString(begin, "yyyyMMdd"), QDate::fromString(end, "yyyyMMdd"));
}

QByteArray TaskSession::CheckExportProgress()
{
    QString retStr;
    if(taskType != TASK_EXPORT_RECORD)
    {
        retStr = QString("{\
                         \"code\": -1,\
                         \"msg\": \"%1\"\
                        }").arg(QString::fromUtf8("任务状态错误"));
        return retStr.toUtf8();
    }

    if(taskProgress == 100)
    {
        QByteArray ret = QByteArray(tempToPdf->getDownloadPath());
        pThread->quit();
        pThread->wait();
        taskType = TASK_NONE;
        QTimer::singleShot(2000, this, SLOT(sessionFinishSlot()));
        return ret;
    }
    else
    {
        retStr = QString("{\
                        \"code\": 1,\
                        \"msg\": \"%1\",\
                        \"progress\":%2\
                        }").arg(QString::fromUtf8("正在生成数据")).arg(taskProgress);
        return retStr.toUtf8();
    }
}

void TaskSession::writeData(QString opt, QByteArray qba)
{
    if(opt != curOpt)
        return;
    qDebug()<<"[writeData]"<<qba;
    taskSocket->write(qba);
    taskSocket->waitForBytesWritten();
}

void TaskSession::writeData(QByteArray qba)
{
    qDebug()<<"[writeData]"<<qba;
    taskSocket->write(qba);
    taskSocket->waitForBytesWritten();
}

void TaskSession::fastReturn(QString msg, int code)
{
    QString retStr = QString("{\
                           \"code\": %1,\
                           \"msg\": \"%2\"\
                      }").arg(code).arg(msg);
    QByteArray retQba = retStr.toUtf8();
    writeData(retQba);
}

void TaskSession::readSessionData()
{
    QByteArray qba = taskSocket->readAll();
    qDebug()<<"[readSessionData]"<<qba;
    recvParams(qba);
//    recvParams(qba);
    return;
//    QByteArray ret = "{\"test\":\"123\"}";
//    QByteArray head = "HTTP/1.1 200 OK\r\n";
//    head.append("Status Code:200 OK\r\n");
//    head.append("Content-Type: application/json\r\n");
//    QByteArray ret = QByteArray("{\
//                                \"tooltip\": {\
//                                    \"show\": true\
//                                },\
//                                \"legend\": {\
//                                    \"data\": [\"销量\"]\
//                                },\
//                                \"xAxis\": [{\
//                                    \"type\": \"category\",\
//                                    \"data\": [\"衬衫\", \"羊毛衫\", \"雪纺衫\", \"裤子\", \"高跟鞋\", \"袜子\"]\
//                                }],\
//                                \"yAxis\": [{\
//                                    \"type\": \"value\"\
//                                }],\
//                                \"series\": [{\
//                                    \"name\": \"销量\",\
//                                    \"type\": \"bar\",\
//                                    \"data\": [5, 20, 40, 10, 10, 20]\
//                                }]\
//                            }");
//    head.append(QString("Content-Length: %1\r\n").arg(ret.length()));
//    head.append(ret);
//    JECharts* jEcharts = new JECharts();
//    jEcharts->devList.clear();
//    jEcharts->devList<<"03B91ACD";
//    jEcharts->legendList.clear();
//    jEcharts->legendList<<"03B91ACD";
//    QByteArray ret = jEcharts->getEchartJson(7);
//    int pacNum = ret.size()/4096;
//    int lastPac = ret.size()%4096;
//    int i=0;
//    for(i=0; i<pacNum; i++)
//    {
//        qDebug()<<"send"<<taskSocket->write(ret.data()+i*4096, 4096);
//    }
//    if(lastPac)
//    {
//        qDebug()<<"send"<<taskSocket->write(ret.data()+i*4096, lastPac);
//    }
//    taskSocket->write(ret);
//    taskSocket->waitForBytesWritten();
//    qDebug()<<ret.size();
//    TempToPdf* tempToPdf = new TempToPdf();
//    tempToPdf->creatTempPdf(jEcharts->devList, QDate::currentDate().addDays(-365), QDate::currentDate());
//    QTimer::singleShot(5000, this, SLOT(sessionFinishSlot()));
}

void TaskSession::sessionFinishSlot()
{
    while(taskSocket->waitForBytesWritten(2000))
    {
        qApp->exec();
    }
    emit sessionFinished();
}

void TaskSession::updateTaskProgress(int progress)
{
    taskProgress = progress;
//    QString str = QString("{\
//                  \"code\": 1,\
//                  \"msg\":\"正在打包数据\",\
//               \"progress\":%1\
//              }").arg(progress);
//    qDebug()<<str;
//    writeData("ExportDevRecord", str.toUtf8());
}

//void TaskSession::pdfCreateFinish()
//{
//    QString cmd = QString("rm /opt/web/webpages/*.tar.bz2");
//    QByteArray qba = cmd.toLocal8Bit();
//    system(qba.data());
//    QString pdfPath = qApp->applicationDirPath()+PATH_TEMP_PDF;

//    cmd = QString("tar -zcvf /opt/web/webpages/%1 %2*.pdf").arg(recordName).arg(pdfPath);
//    qba = cmd.toLocal8Bit();
//    qDebug()<<"[tarProcess]"<<cmd;
//    system(qba.data());

//    CabinetConfig* config = CabinetConfig::config();

//    QString downLoadPath = QString("http://%1/%2").arg(config->getIp()).arg(recordName);
//    qDebug()<<"[downLoadPath]"<<downLoadPath;
//    QString str = QString("{\
//                  \"code\": 0,\
//                  \"msg\":\"success\",\
//               \"data\":\"%1\"\
//              }").arg(downLoadPath);
//    writeData("ExportDevRecord", str.toUtf8());
//}
